from abstractNodeKomunikacija import AbstractNodeKomunikacija
from commands import Commands
from random import randrange
import time
from worker import WorkerProstiBrojevi
from time import sleep
import threading
from __builtin__ import range

class UDPCLientNode(AbstractNodeKomunikacija):
    def __init__(self, requestId, opseg, sviServeri, listenPort):
        AbstractNodeKomunikacija.__init__(self, listenPort)
        self.requestId = requestId
        self.opseg = opseg
        self.sviServeri = sviServeri
        
        #print "KLIJENT SERVERI" , sviServeri
        
        self.zahtevi = {}
        self.currentChunk = -1
        self.requestedChunk = False
        self.startedWorkingOnChunk = False;
        self.worker = WorkerProstiBrojevi()  # workera treba ubaciti
        self.imaChunkova = True
        self.prostiPoChunku = {}
        self.ostaloProstihDaSePrebace =True
        split = self.opseg.split(',')
        #print split[0] + "AAAAAAAAAAAAAA"
        self.pocetakOpsega = int(split[0]);
        self.krajOpsega = int(split[1]);
        self.brojChunkova = (self.krajOpsega - self.pocetakOpsega) / Commands.VELICINA_CHUNKA;
        if(self.krajOpsega - self.pocetakOpsega)% Commands.VELICINA_CHUNKA !=0:
            self.brojChunkova+=1
        
        print "PRAVIM NOVI UDP KLIJENT"
        
    def obradiPaket(self, recieveAddress, recievePort, requestID, komanda, telo):
        #print "Obradjujem paket"
        if komanda == Commands.NEW_NODE:
            randomServer = self.sviServeri[randrange(len(self.sviServeri))]
            self.sendPaketWithCustomHeader(recieveAddress, recievePort, randomServer[0], randomServer[1], requestID, komanda, telo)
        elif komanda == Commands.HERE_IS_A_CHUNK:
            #print "DOBIO SAM CHUNK"
            self.currentChunk = int(telo)
            if self.currentChunk !=-1:
                #print "aaa",self.requestId, self.zahtevi
                self.zahtevi.pop(int(requestID))
        elif komanda == Commands.ALL_FINISHED:
            self.imaChunkova = False
        elif komanda == Commands.HERE_IS_INFO:
            split = telo.split(';')
            info = split[0]
            print "ETA: " + str(info)
            brServera =int(split[1])
            sviServeriUpdate = []
            j =2
            for i in range(0,brServera):
                sviServeriUpdate.append([split[j],int(split[j+1])])
                j+=2
            self.sviServeri = sviServeriUpdate
        elif komanda == Commands.HERE_ARE_PRIMES:
            split = telo.split(';')
            chunkId = int(split[0])
            prosti = []
            for i in range(0,len(split)):
                prost = int(split[i])
                prosti.append(prost) 
            self.prostiPoChunku.update({chunkId : prosti})            
             
    def obratiSeServerimaZaChunk(self):
        #print "Obrati se serverima za chunk"
        randomServer = self.sviServeri[randrange(len(self.sviServeri))]
        self.requestChunkID = self.requestId
        self.sendPaket(randomServer[0], randomServer[1], self.requestId, Commands.GIVE_ME_NEW_CHUNK, "EMPTY")
        self.requestId += 1
        self.requestedChunk = True
        self.zahtevi.update({self.requestChunkID: Commands.HERE_IS_A_CHUNK})
        self.requestChunkTimestamp = self.getTime()
           
    def start(self):
        #print "Krenuo sam start iz clienta"
        self.worker.startJob()
        self.startRecieving()
        self.periodicnoRadjenjeStvariTred = threading.Thread(target=self.periodicnoRadjenjeStvariMethod, args=())
        self.periodicnoRadjenjeStvariTred.daemon = True
        self.periodicnoRadjenjeStvariTred.start()
        while True:
            try:
                time.sleep(0.001)
            except:
                print "Ja vise nikada necu da spavam"
            continue
    
    def getTime(self):
        currTimeMill = lambda: int(round(time.time() * 1000))
        return currTimeMill()
       
    def periodicnoRadjenjeStvariMethod(self):
        while self.imaChunkova:
            if not self.worker.working:
                if self.startedWorkingOnChunk ==True: #radio i zavrsio javi serveru sve proste
                    timeStamp = self.getTime()
                    for p in self.worker.prosti:
                        print p
                        sb =";"
                        sb += str(p)
                    self.worker.prosti = []
                    randomServer = self.sviServeri[randrange(len(self.sviServeri))]
                    teloPoruke = str(self.currentChunk) +";" +str(timeStamp)
                    self.sendPaket(randomServer[0], randomServer[1], self.requestId, Commands.CLIENT_FINISHED_CHUNK, teloPoruke+sb)
                    self.requestId+=1
                    self.startedWorkingOnChunk = False
                    self.requestedChunk = False
                elif self.requestedChunk == True:
                    if self.zahtevi.has_key(self.requestChunkID):
                        #jos mu nije odgovorio
                        curTime = self.getTime()
                        if (curTime - self.requestChunkTimestamp) > 10000:
                            self.zahtevi.pop(int(self.requestChunkID))
                            self.requestedChunk = False
                    else:
                        #print "Client set CHunkkk"
                        timeStamp1 = self.getTime()
                        self.worker.setChunk(self.currentChunk, self.currentChunk*Commands.VELICINA_CHUNKA +1, (self.currentChunk+1)*Commands.VELICINA_CHUNKA)
                        self.startedWorkingOnChunk = True
                        #posalji serveru da sam krenuo da radim
                        randomServer = self.sviServeri[randrange(self.sviServeri.__len__())]
                        self.requestChunkID = self.requestId
                        teloPoruke = str(self.currentChunk) +";" +str(timeStamp1)
                        self.sendPaket(randomServer[0], randomServer[1], self.requestId, Commands.CLIENT_STARTED_CHUNK, teloPoruke)
                        self.requestId+=1
                elif self.requestedChunk==False:
                    self.obratiSeServerimaZaChunk()
                    continue
            #SLANJE UPITA SERVERU O LISTI SERVERA, I OSTALE INFO(ETA..)
            randomServer = self.sviServeri[randrange(len(self.sviServeri))] 
            self.sendPaket(randomServer[0], randomServer[1], self.requestId, Commands.GIVE_ME_NEW_INFO, "EMPTY") 
            self.requestId+=1
            sleep(5)
        while self.ostaloProstihDaSePrebace:
            print "svi serveri ", self.sviServeri
            print "broj cankova ", self.brojChunkova 
            for serv in self.sviServeri:
                for i in range(0,self.brojChunkova):
                    sviTu = True
                    if i not in self.prostiPoChunku:
                        sviTu=False
                        self.sendPaket(serv[0], serv[1], self.requestId, Commands.GIVE_ME_PRIMES, str(i))
                        self.requestId+=1
                        
                        sleep(0.03)
                    if sviTu == True:
                        self.ostaloProstihDaSePrebace = False
                if not self.ostaloProstihDaSePrebace:
                    break
                
            sleep(0.5)
        print "RESENJE!: ", self.prostiPoChunku

        
        
                  
                            
